<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Projekt Godsword: Working Demo</title>
        <link rel="preload" href="resources/dragonslapper.woff" as="font" type="font/woff" crossorigin>
        <link rel="icon" href="favicon.ico" type="image/x-icon">
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    </head>

    <style>
        @font-face {
            font-family: "DragonSlapper";
            src: url(resources/dragonslapper.woff);
        }

		#blocker {
			position: fixed;
         top: 0px;
         left: 0px;
         z-index: 100000;

			width: 100%;
			height: 100%;

			background-color: rgba(0,0,0,0.5);
		}

      #instructions {
			width: 100%;
			height: 100%;

			display: -webkit-box;
			display: -moz-box;
			display: box;

			-webkit-box-orient: horizontal;
			-moz-box-orient: horizontal;
			box-orient: horizontal;

			-webkit-box-pack: center;
			-moz-box-pack: center;
			box-pack: center;

			-webkit-box-align: center;
			-moz-box-align: center;
			box-align: center;

			color: #eeeeee;
			text-align: center;

			cursor: pointer;
        }
    </style>

    <body>
        <div id="blocker" style="display: block;">
            <div id="instructions">
			    <!-- <span style="font-size:40px">Click to begin</span> <br> -->
			    <span style="font-family:DragonSlapper;font-size:80px">
                NEURAL MMO CLIENT</span> <br>
        	    <b>WASD/middle mouse</b> pitch/yaw, <b>arrow keys</b> pan <br/>
			    <b>scroll wheel</b> zoom, <b>t key</b> toggle overlays
            </div>
        </div>


        <div id="client_container" style="display: block; position: fixed; top: 0px; left: 0px">
         <br /></div>
        <div id="counts_container" style="display: block; position: fixed; top: 0px; left: 0px">
         <br /></div>
        <div id="values_container" style="display: block; position: fixed; top: 0px; left: 0px">
         <br /></div>

        <script src="three.js/build/three.js"></script>
        <script src="three.js/examples/js/utils/BufferGeometryUtils.js"></script>
        <script src="three.js/examples/js/ImprovedNoise.js"></script>
        <script src="three.js/examples/js/WebGL.js"></script>
        <script src="three.js/examples/js/loaders/OBJLoader.js"></script>
        <script src="three.js/examples/js/loaders/MTLLoader.js"></script>
        <script src="three.js/examples/js/libs/stats.min.js"></script>
        <script src="three.js/examples/js/objects/Water.js"></script>
        <script src="three.js/examples/js/objects/Sky.js"></script>
        <script src="threex/WindowResize.js"></script>
        <script src="threex/FullScreen.js"></script>

        <script src="comms.js"></script>
        <script src="consts.js"></script>
        <script src="OrbitControls.js"></script>
        <script src="client.js" type="module"></script>


        <script id="vs_depth" type="x-shader/x-vertex">
        uniform sampler2D bumpTexture;
        uniform float tileScale;

        varying float vAmount; varying vec2 vUV;
        varying vec3 newPosition;

        vec2 tilePos;
        float tile;
        float border;
        float val;
        float tol = 0.025;
        float mag = 1.0;
        float nTiles = 80.00001;
void main() {
            vUV = uv;
            tilePos = floor(position.xz / 64.0);
            vAmount = 255.0*texture2D(bumpTexture, tilePos/nTiles).r;

            //Check if we are on a border
            vec2 err = position.xz/64.0 - tilePos;


            if (err.x < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.x < tol && err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }


            if (position.x == 0.0 || position.z == 0.0 || 
                  position.x / 64.0 == 80.0 || position.z / 64.0 == 80.0) {
               vAmount = 0.0;
            }

            // move the position along the normal
            newPosition = position + normal * tileScale * vAmount;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(
                newPosition, 1.0 );
}
 

        </script>

        <script id="vertexShader" type="x-shader/x-vertex">
        uniform sampler2D bumpTexture;
        uniform float tileScale;

        varying float vAmount; varying vec2 vUV;
        varying vec3 newPosition;

        vec2 tilePos;
        float tile;
        float border;
        float val;
        float tol = 0.025;
        float mag = 1.0;
        float nTiles = 80.00001;
//varying vec3 vViewPosition;
//varying vec3 vNormal;

        void main()
        {
            //vec3 position = vec3(position.x + 64.0*40.0, position.y+64.0*40.0, position.z);
            vUV = uv;
            tilePos = floor(position.xz / 64.0);
            vAmount = 255.0*texture2D(bumpTexture, tilePos/nTiles).r;

            //Check if we are on a border
            vec2 err = position.xz/64.0 - tilePos;


            if (err.x < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.x < tol && err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }


            if (position.x == 0.0 || position.z == 0.0 || 
                  position.x / 64.0 == 80.0 || position.z / 64.0 == 80.0) {
               vAmount = 0.0;
            }

            // move the position along the normal
            newPosition = position + normal * tileScale * vAmount;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(
                newPosition, 1.0 );
        }
        </script>

        <script id="fragmentShader" type="x-shader/x-vertex">
        uniform sampler2D oceanTexture;
        uniform sampler2D sandyTexture;
        uniform sampler2D grassTexture;
        uniform sampler2D forestTexture;
        uniform sampler2D lavaTexture;
        uniform sampler2D scrubTexture;
        uniform sampler2D stoneTexture;
        uniform sampler2D tileTexture;

        vec2 tilePos;
        float tile;
        float tol = 0.05;

        varying vec2 vUV;

        varying float vAmount;
        varying vec3 newPosition;
        float nTiles = 80.0001;
        vec4 water;

        void main() {
            //Check 80 minus
            //tilePos = 80.0 - floor(newPosition.xy / 64.0);
            //vec2 tileUV = newPosition.xz/64.0 - floor(newPosition.xz / 64.00);
            tilePos = floor(newPosition.xz / 64.0);
            vec2 tileUV = newPosition.xz/64.0;
            tile = 255.0 * texture2D(tileTexture, tilePos/nTiles ).r;

            vec4 grass  = texture2D( grassTexture,  tileUV* 1.0 );
            vec4 forest = texture2D( forestTexture, tileUV* 1.0 );
            vec4 lava   = texture2D( lavaTexture,   tileUV* 1.0 );
            vec4 scrub  = texture2D( scrubTexture,  tileUV* 1.0 );
            vec4 stone  = texture2D( stoneTexture,  tileUV* 1.0 );
            vec4 sandy  = texture2D( sandyTexture,  tileUV* 1.0 );
            /*
            vec4 sandy = (
                smoothstep(0.24, 0.27, vAmount) -
                smoothstep(0.28, 0.31, vAmount)
                ) * texture2D( sandyTexture, tileUV* 10.0 );
            */

            lava = lava * float(tile==0.0);
            water = sandy * float(tile == 1.0);
            grass = grass * float(tile == 2.0 );
            scrub = scrub * float(tile == 3.0);
            forest = forest * float(tile==4.0);
            stone = stone * float(tile==5.0);
            gl_FragColor = (vec4(0.0, 0.0, 0.0, 1.0) + 
                  water + grass +
                  forest + scrub + stone + lava);

            float modx = tilePos.x - (2.0 * floor(tilePos.x/2.0));
            float mody = tilePos.y - (2.0 * floor(tilePos.y/2.0));
            gl_FragColor = 0.8*gl_FragColor + 0.2*gl_FragColor*(abs(modx-mody));
            //Check if we are on a border
            vec2 err = newPosition.xz/64.0 - tilePos;

            //float xcolor = newPosition.x /10000.0;
            //float ycolor = newPosition.z /10000.0;
            //gl_FragColor = vec4(xcolor, ycolor, 0.0, 1.0);

            //Debug shader
            /*
            if (err.x < tol) {
               gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
            }

            if (err.y < tol) {
               gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }

            if (err.x < tol && err.y < tol) {
               gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
            }
            */
        }
        </script>

        <script id="statVertexShader" type="x-shader/x-vertex">
        uniform vec3 scale;
        varying vec2 vUV;

        void main()
        {
            vUV = uv;
            //gl_Position = projectionMatrix * (modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(position.x, position.y, 0.0, 0.0));
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
        }
        </script>

        <script id="statFragmentShader" type="x-shader/x-vertex">
        uniform vec3 color;
        uniform float width;
        uniform float val;
        varying vec2 vUV;

        void main() {
           if (vUV.x > val / width) {
              gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
           } else {
              gl_FragColor = vec4(color.x, color.y, color.z, 1.0);
           }
        }
        </script>


        <script id="phongVertexShader" type="x-shader/x-vertex">

        uniform sampler2D bumpTexture;
        uniform float tileScale;

        varying float vAmount; varying vec2 vUV;
        varying vec3 newPosition;

        vec2 tilePos;
        float tile;
        float border;
        float val;
        float tol = 0.025;
        float mag = 1.0;
        float nTiles = 80.00001;


#define PHONG

varying vec3 vViewPosition;

#ifndef FLAT_SHADED

   varying vec3 vNormal;

#endif

#include <common>
#include <uv_pars_vertex>
#include <uv2_pars_vertex>
#include <displacementmap_pars_vertex>
#include <envmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>

void main() {

   #include <uv_vertex>
   #include <uv2_vertex>
   #include <color_vertex>

   #include <beginnormal_vertex>
   #include <morphnormal_vertex>
   #include <skinbase_vertex>
   #include <skinnormal_vertex>
   #include <defaultnormal_vertex>

#ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED

   vNormal = normalize( transformedNormal );

#endif

   #include <begin_vertex>
   #include <morphtarget_vertex>
   #include <skinning_vertex>
   #include <displacementmap_vertex>
   #include <project_vertex>

            //vec3 position = vec3(position.x + 64.0*40.0, position.y+64.0*40.0, position.z);
            vUV = uv;
            tilePos = floor(position.xz / 64.0);
            vAmount = 255.0*texture2D(bumpTexture, tilePos/nTiles).r;

            //Check if we are on a border
            vec2 err = position.xz/64.0 - tilePos;


            if (err.x < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.x < tol && err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }


            if (position.x == 0.0 || position.z == 0.0 || 
                  position.x / 64.0 == 80.0 || position.z / 64.0 == 80.0) {
               vAmount = 0.0;
            }

            // move the position along the normal
            newPosition = position + normal * tileScale * vAmount;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(
                newPosition, 1.0 );
 
   #include <logdepthbuf_vertex>
   #include <clipping_planes_vertex>

   vViewPosition = - mvPosition.xyz;

   #include <worldpos_vertex>
   #include <envmap_vertex>
   #include <shadowmap_vertex>
   #include <fog_vertex>

}

        </script>

        <script id="phongFragmentShader" type="x-shader/x-fragment">
        uniform sampler2D oceanTexture;
        uniform sampler2D sandyTexture;
        uniform sampler2D grassTexture;
        uniform sampler2D forestTexture;
        uniform sampler2D lavaTexture;
        uniform sampler2D scrubTexture;
        uniform sampler2D stoneTexture;
        uniform sampler2D tileTexture;

        vec2 tilePos;
        float tile;
        float tol = 0.05;

        varying vec2 vUV;

        varying float vAmount;
        varying vec3 newPosition;
        float nTiles = 80.0001;
        vec4 water;

#define PHONG

uniform vec3 diffuse;
uniform vec3 emissive;
uniform vec3 specular;
uniform float shininess;
uniform float opacity;

#include <common>
#include <packing>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <uv2_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <envmap_pars_fragment>
#include <gradientmap_pars_fragment>
#include <fog_pars_fragment>
#include <bsdfs>
#include <lights_pars_begin>
#include <lights_phong_pars_fragment>
#include <shadowmap_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>

void main() {

   #include <clipping_planes_fragment>

   vec4 diffuseColor = vec4( diffuse, opacity );
   ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
   vec3 totalEmissiveRadiance = emissive;

   #include <logdepthbuf_fragment>
   #include <map_fragment>
   #include <color_fragment>
   #include <alphamap_fragment>
   #include <alphatest_fragment>
   #include <specularmap_fragment>
   #include <normal_fragment_begin>
   #include <normal_fragment_maps>
   #include <emissivemap_fragment>

   // accumulation
   #include <lights_phong_fragment>
   #include <lights_fragment_begin>
   #include <lights_fragment_maps>
   #include <lights_fragment_end>

   // modulation
   #include <aomap_fragment>

   vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;

   #include <envmap_fragment>

   gl_FragColor = vec4( outgoingLight, diffuseColor.a );

            tilePos = floor(newPosition.xz / 64.0);
            vec2 tileUV = newPosition.xz/64.0;
            tile = 255.0 * texture2D(tileTexture, tilePos/nTiles ).r;

            vec4 grass  = texture2D( grassTexture,  tileUV* 2.0 );
            vec4 forest = texture2D( forestTexture, tileUV* 2.0 );
            vec4 lava   = texture2D( lavaTexture,   tileUV* 2.0 );
            vec4 scrub  = texture2D( scrubTexture,  tileUV* 2.0 );
            vec4 stone  = texture2D( stoneTexture,  tileUV* 3.0 );
            vec4 sandy  = texture2D( sandyTexture,  tileUV* 2.0 );
            /*
            vec4 sandy = (
                smoothstep(0.24, 0.27, vAmount) -
                smoothstep(0.28, 0.31, vAmount)
                ) * texture2D( sandyTexture, tileUV* 10.0 );
            */

            lava = lava * float(tile==0.0);
            water = sandy * float(tile == 1.0);
            grass = grass * float(tile == 2.0 );
            scrub = scrub * float(tile == 3.0);
            forest = forest * float(tile==4.0);
            stone = stone * float(tile==5.0);
            gl_FragColor = (vec4(0.0, 0.0, 0.0, 1.0) + 
                  water + grass +
                  forest + scrub + stone + lava);

            float modx = tilePos.x - (2.0 * floor(tilePos.x/2.0));
            float mody = tilePos.y - (2.0 * floor(tilePos.y/2.0));
            gl_FragColor = 0.9*gl_FragColor + 0.1*gl_FragColor*(abs(modx-mody));

            gl_FragColor = vec4(gl_FragColor.xyz * outgoingLight, diffuseColor.a);

            //Check if we are on a border
            vec2 err = newPosition.xz/64.0 - tilePos;

            //float xcolor = newPosition.x /10000.0;
            //float ycolor = newPosition.z /10000.0;
            //gl_FragColor = vec4(xcolor, ycolor, 0.0, 1.0);

            //Debug shader
            /*
            if (err.x < tol) {
               gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
            }

            if (err.y < tol) {
               gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }

            if (err.x < tol && err.y < tol) {
               gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
            }
            */
 
   #include <tonemapping_fragment>
   #include <encodings_fragment>
   #include <fog_fragment>
   #include <premultiplied_alpha_fragment>
   #include <dithering_fragment>

}
        </script>

        <script id="phongValueVertexShader" type="x-shader/x-vertex">

        uniform sampler2D bumpTexture;
        uniform float tileScale;

        varying float vAmount; varying vec2 vUV;
        varying vec3 newPosition;

        vec2 tilePos;
        float tile;
        float border;
        float val;
        float tol = 0.025;
        float mag = 1.0;
        float nTiles = 80.00001;


#define PHONG

varying vec3 vViewPosition;

#ifndef FLAT_SHADED

   varying vec3 vNormal;

#endif

#include <common>
#include <uv_pars_vertex>
#include <uv2_pars_vertex>
#include <displacementmap_pars_vertex>
#include <envmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>

void main() {

   #include <uv_vertex>
   #include <uv2_vertex>
   #include <color_vertex>

   #include <beginnormal_vertex>
   #include <morphnormal_vertex>
   #include <skinbase_vertex>
   #include <skinnormal_vertex>
   #include <defaultnormal_vertex>

#ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED

   vNormal = normalize( transformedNormal );

#endif

   #include <begin_vertex>
   #include <morphtarget_vertex>
   #include <skinning_vertex>
   #include <displacementmap_vertex>
   #include <project_vertex>

            //vec3 position = vec3(position.x + 64.0*40.0, position.y+64.0*40.0, position.z);
            vUV = uv;
            tilePos = floor(position.xz / 64.0);
            vAmount = 255.0*texture2D(bumpTexture, tilePos/nTiles).r;

            //Check if we are on a border
            vec2 err = position.xz/64.0 - tilePos;


            if (err.x < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.x < tol && err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }


            if (position.x == 0.0 || position.z == 0.0 || 
                  position.x / 64.0 == 80.0 || position.z / 64.0 == 80.0) {
               vAmount = 0.0;
            }

            // move the position along the normal
            newPosition = position + normal * tileScale * vAmount;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(
                newPosition, 1.0 );
 
   #include <logdepthbuf_vertex>
   #include <clipping_planes_vertex>

   vViewPosition = - mvPosition.xyz;

   #include <worldpos_vertex>
   #include <envmap_vertex>
   #include <shadowmap_vertex>
   #include <fog_vertex>

}

        </script>

        <script id="phongValueFragmentShader" type="x-shader/x-fragment">
        uniform sampler2D oceanTexture;
        uniform sampler2D sandyTexture;
        uniform sampler2D grassTexture;
        uniform sampler2D forestTexture;
        uniform sampler2D lavaTexture;
        uniform sampler2D scrubTexture;
        uniform sampler2D stoneTexture;
        uniform sampler2D tileTexture;
        uniform sampler2D valueTex;

        vec2 tilePos;
        float tile;
        vec3 val;
        float tol = 0.05;

        varying vec2 vUV;

        varying float vAmount;
        varying vec3 newPosition;
        float nTiles = 80.0001;
        vec4 water;

#define PHONG

uniform vec3 diffuse;
uniform vec3 emissive;
uniform vec3 specular;
uniform float shininess;
uniform float opacity;

#include <common>
#include <packing>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <uv2_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <envmap_pars_fragment>
#include <gradientmap_pars_fragment>
#include <fog_pars_fragment>
#include <bsdfs>
#include <lights_pars_begin>
#include <lights_phong_pars_fragment>
#include <shadowmap_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>

void main() {

   #include <clipping_planes_fragment>

   vec4 diffuseColor = vec4( diffuse, opacity );
   ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
   vec3 totalEmissiveRadiance = emissive;

   #include <logdepthbuf_fragment>
   #include <map_fragment>
   #include <color_fragment>
   #include <alphamap_fragment>
   #include <alphatest_fragment>
   #include <specularmap_fragment>
   #include <normal_fragment_begin>
   #include <normal_fragment_maps>
   #include <emissivemap_fragment>

   // accumulation
   #include <lights_phong_fragment>
   #include <lights_fragment_begin>
   #include <lights_fragment_maps>
   #include <lights_fragment_end>

   // modulation
   #include <aomap_fragment>

   vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;

   #include <envmap_fragment>

   gl_FragColor = vec4( outgoingLight, diffuseColor.a );

            tilePos = floor(newPosition.xz / 64.0);
            vec2 tileUV = newPosition.xz/64.0;
            tile = 255.0 * texture2D(tileTexture, tilePos/nTiles ).r;
            val  = texture2D(valueTex, tilePos/nTiles ).rgb;
            //val  = 255.0 * texture2D(valueTex, tilePos/nTiles ).r;

            vec4 grass  = texture2D( grassTexture,  tileUV* 2.0 );
            vec4 forest = texture2D( forestTexture, tileUV* 2.0 );
            vec4 lava   = texture2D( lavaTexture,   tileUV* 2.0 );
            vec4 scrub  = texture2D( scrubTexture,  tileUV* 2.0 );
            vec4 stone  = texture2D( stoneTexture,  tileUV* 3.0 );
            vec4 sandy  = texture2D( sandyTexture,  tileUV* 2.0 );
            /*
            vec4 sandy = (
                smoothstep(0.24, 0.27, vAmount) -
                smoothstep(0.28, 0.31, vAmount)
                ) * texture2D( sandyTexture, tileUV* 10.0 );
            */

            lava = lava * float(tile==0.0);
            water = sandy * float(tile == 1.0);
            grass = grass * float(tile == 2.0 );
            scrub = scrub * float(tile == 3.0);
            forest = forest * float(tile==4.0);
            stone = stone * float(tile==5.0);
            gl_FragColor = (vec4(0.0, 0.0, 0.0, 1.0) + 
                  water + grass +
                  forest + scrub + stone + lava);

            float modx = tilePos.x - (2.0 * floor(tilePos.x/2.0));
            float mody = tilePos.y - (2.0 * floor(tilePos.y/2.0));
            gl_FragColor = 0.9*gl_FragColor + 0.1*gl_FragColor*(abs(modx-mody));

            gl_FragColor = vec4(gl_FragColor.xyz * outgoingLight, diffuseColor.a);

            gl_FragColor = 0.4*gl_FragColor + 0.6*vec4(val.r, val.g, val.b, 1.0);
            //Check if we are on a border
            vec2 err = newPosition.xz/64.0 - tilePos;

            //float xcolor = newPosition.x /10000.0;
            //float ycolor = newPosition.z /10000.0;
            //gl_FragColor = vec4(xcolor, ycolor, 0.0, 1.0);

            //Debug shader
            /*
            if (err.x < tol) {
               gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
            }

            if (err.y < tol) {
               gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }

            if (err.x < tol && err.y < tol) {
               gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
            }
            */
 
   #include <tonemapping_fragment>
   #include <encodings_fragment>
   #include <fog_fragment>
   #include <premultiplied_alpha_fragment>
   #include <dithering_fragment>

}
        </script>


        <script id="phongCountsVertexShader" type="x-shader/x-vertex">

        uniform sampler2D bumpTexture;
        uniform float tileScale;

        varying float vAmount; varying vec2 vUV;
        varying vec3 newPosition;

        vec2 tilePos;
        float tile;
        float border;
        float val;
        float tol = 0.025;
        float mag = 1.0;
        float nTiles = 80.00001;


#define PHONG

varying vec3 vViewPosition;

#ifndef FLAT_SHADED

   varying vec3 vNormal;

#endif

#include <common>
#include <uv_pars_vertex>
#include <uv2_pars_vertex>
#include <displacementmap_pars_vertex>
#include <envmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>

void main() {

   #include <uv_vertex>
   #include <uv2_vertex>
   #include <color_vertex>

   #include <beginnormal_vertex>
   #include <morphnormal_vertex>
   #include <skinbase_vertex>
   #include <skinnormal_vertex>
   #include <defaultnormal_vertex>

#ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED

   vNormal = normalize( transformedNormal );

#endif

   #include <begin_vertex>
   #include <morphtarget_vertex>
   #include <skinning_vertex>
   #include <displacementmap_vertex>
   #include <project_vertex>

            //vec3 position = vec3(position.x + 64.0*40.0, position.y+64.0*40.0, position.z);
            vUV = uv;
            tilePos = floor(position.xz / 64.0);
            vAmount = 255.0*texture2D(bumpTexture, tilePos/nTiles).r;

            //Check if we are on a border
            vec2 err = position.xz/64.0 - tilePos;


            if (err.x < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }

            if (err.x < tol && err.y < tol) {
               val = 255.0*texture2D(bumpTexture, vec2(tilePos.x-1.0, tilePos.y-1.0)/nTiles).r;
               if (val == 1.0) { vAmount = mag; }
            }


            if (position.x == 0.0 || position.z == 0.0 || 
                  position.x / 64.0 == 80.0 || position.z / 64.0 == 80.0) {
               vAmount = 0.0;
            }

            // move the position along the normal
            newPosition = position + normal * tileScale * vAmount;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(
                newPosition, 1.0 );
 
   #include <logdepthbuf_vertex>
   #include <clipping_planes_vertex>

   vViewPosition = - mvPosition.xyz;

   #include <worldpos_vertex>
   #include <envmap_vertex>
   #include <shadowmap_vertex>
   #include <fog_vertex>

}

        </script>

        <script id="phongCountsFragmentShader" type="x-shader/x-fragment">
        uniform sampler2D oceanTexture;
        uniform sampler2D sandyTexture;
        uniform sampler2D grassTexture;
        uniform sampler2D forestTexture;
        uniform sampler2D lavaTexture;
        uniform sampler2D scrubTexture;
        uniform sampler2D stoneTexture;
        uniform sampler2D tileTexture;

        uniform sampler2D countZeroTex;
        uniform sampler2D countOneTex;
        uniform sampler2D countTwoTex;
        uniform sampler2D countThreeTex;
        uniform sampler2D countFourTex;
        uniform sampler2D countFiveTex;
        uniform sampler2D countSixTex;
        uniform sampler2D countSevenTex;

        float countZero;
        float countOne;
        float countTwo;
        float countThree;
        float countFour;
        float countFive;
        float countSix;
        float countSeven;

        vec2 tilePos;
        float tile;
        float tol = 0.05;
        float clr = 5.0;

        varying vec2 vUV;

        varying float vAmount;
        varying vec3 newPosition;
        float nTiles = 80.0001;
        vec4 water;

#define PHONG

uniform vec3 diffuse;
uniform vec3 emissive;
uniform vec3 specular;
uniform float shininess;
uniform float opacity;

#include <common>
#include <packing>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <uv2_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <envmap_pars_fragment>
#include <gradientmap_pars_fragment>
#include <fog_pars_fragment>
#include <bsdfs>
#include <lights_pars_begin>
#include <lights_phong_pars_fragment>
#include <shadowmap_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>

void main() {

   #include <clipping_planes_fragment>

   vec4 diffuseColor = vec4( diffuse, opacity );
   ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
   vec3 totalEmissiveRadiance = emissive;

   #include <logdepthbuf_fragment>
   #include <map_fragment>
   #include <color_fragment>
   #include <alphamap_fragment>
   #include <alphatest_fragment>
   #include <specularmap_fragment>
   #include <normal_fragment_begin>
   #include <normal_fragment_maps>
   #include <emissivemap_fragment>

   // accumulation
   #include <lights_phong_fragment>
   #include <lights_fragment_begin>
   #include <lights_fragment_maps>
   #include <lights_fragment_end>

   // modulation
   #include <aomap_fragment>

   vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;

   #include <envmap_fragment>

   gl_FragColor = vec4( outgoingLight, diffuseColor.a );

            tilePos = floor(newPosition.xz / 64.0);
            vec2 tileUV = newPosition.xz/64.0;
            tile  = 255.0 * texture2D(tileTexture, tilePos/nTiles ).r;

            countZero = 255.0 * texture2D(countZeroTex, tilePos/nTiles ).r / clr;
            countOne = 255.0 * texture2D(countOneTex, tilePos/nTiles ).r / clr;
            countTwo = 255.0 * texture2D(countTwoTex, tilePos/nTiles ).r / clr;
            countThree = 255.0 * texture2D(countThreeTex, tilePos/nTiles ).r / clr;
            countFour = 255.0 * texture2D(countFourTex, tilePos/nTiles ).r / clr;
            countFive = 255.0 * texture2D(countFiveTex, tilePos/nTiles ).r / clr;
            countSix = 255.0 * texture2D(countSixTex, tilePos/nTiles ).r / clr;
            countSeven = 255.0 * texture2D(countSevenTex, tilePos/nTiles ).r / clr;

            vec4 grass  = texture2D( grassTexture,  tileUV* 2.0 );
            vec4 forest = texture2D( forestTexture, tileUV* 2.0 );
            vec4 lava   = texture2D( lavaTexture,   tileUV* 2.0 );
            vec4 scrub  = texture2D( scrubTexture,  tileUV* 2.0 );
            vec4 stone  = texture2D( stoneTexture,  tileUV* 3.0 );
            vec4 sandy  = texture2D( sandyTexture,  tileUV* 2.0 );

            lava = lava * float(tile==0.0);
            water = sandy * float(tile == 1.0);
            grass = grass * float(tile == 2.0 );
            scrub = scrub * float(tile == 3.0);
            forest = forest * float(tile==4.0);
            stone = stone * float(tile==5.0);

            gl_FragColor = (vec4(0.0, 0.0, 0.0, 1.0) + 
                  water + grass +
                  forest + scrub + stone + lava);

            gl_FragColor = 0.2*gl_FragColor;

            gl_FragColor = gl_FragColor + vec4(countZero, 0.0, 0.0, 1.0);
            gl_FragColor = gl_FragColor + vec4(countOne, 0.5*countOne, 0.0, 1.0);
            gl_FragColor = gl_FragColor + vec4(countTwo, countTwo, 0.0, 1.0);
            gl_FragColor = gl_FragColor + vec4(0.0, countThree, 0.0, 1.0);
            gl_FragColor = gl_FragColor + vec4(0.0, countFour, 0.5*countFour, 1.0);
            gl_FragColor = gl_FragColor + vec4(0.0, countFive, countFive, 1.0);
            gl_FragColor = gl_FragColor + vec4(0.0, 0.0, countSix, 1.0);
            gl_FragColor = gl_FragColor + vec4(0.5*countSeven, 0.0, countSeven, 1.0);

            float modx = tilePos.x - (2.0 * floor(tilePos.x/2.0));
            float mody = tilePos.y - (2.0 * floor(tilePos.y/2.0));
            gl_FragColor = 0.9*gl_FragColor + 0.1*gl_FragColor*(abs(modx-mody));

            gl_FragColor = vec4(gl_FragColor.xyz * outgoingLight, diffuseColor.a);

            //Check if we are on a border
            vec2 err = newPosition.xz/64.0 - tilePos;

            //float xcolor = newPosition.x /10000.0;
            //float ycolor = newPosition.z /10000.0;
            //gl_FragColor = vec4(xcolor, ycolor, 0.0, 1.0);

            //Debug shader
            /*
            if (err.x < tol) {
               gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
            }

            if (err.y < tol) {
               gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }

            if (err.x < tol && err.y < tol) {
               gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
            }
            */
 
   #include <tonemapping_fragment>
   #include <encodings_fragment>
   #include <fog_fragment>
   #include <premultiplied_alpha_fragment>
   #include <dithering_fragment>

}
        </script>
 
    </body>
</html>
